TerraformでAWSのIaCを始める・始めたばかりの人へ #devio2024 #cm_odyssey
DevelopersIO 2024 OSAKAにて、「TerraformでAWSのIaCを始める・始めたばかりの人へ」という内容で登壇いたしました。お越しいただいた皆様、ありがとうございました!
本ブログはその内容をブログ向けに改変したものになります。
ゴール
- Terraformを使ったこと無い方には、Terraformの使い方や魅力を知っていただき、「使ってみよう」と思っていただくこと
- すでにTerraformをお使いの方には、より良い使い方を持ち帰っていただくこと
- ※ タイトルに「AWS」とありますが、あまりAWS関係ありません。AWSを使われない方でも楽しんでいただける内容になっているかなと思います。
自己紹介
かずえと申します。HashiCorp Ambassadorsという制度があります。HashiCorpというのはTerraformの開発元の会社なのですが、そのHashiCorpの製品のコミュニティに貢献した人を表彰する制度です。そちらに2年連続選出いただいております。
- 「HashiCorp Ambassadors 2023」にAWS事業本部の高国、CX事業本部の数枝、営業統括本部の大瀧が選出されました | クラスメソッド株式会社
- 「HashiCorp Ambassadors 2024」にCX事業本部の数枝、AWS事業本部の高国、佐藤が選出されました | クラスメソッド株式会社
最近気をつけているのは「Terraform」のアクセントです。特にアクセント無く発音していたのですが、英語圏ではアクセントはアタマの「テ」の部分に来るというのを最近知りました。ですので、そのアクセントで発音するように気をつけています。ですが正直まだ全然矯正できていません。
Terraformとは
- IaC (Infrastructure as Code) ツール。インフラリソースやクラウドリソースなどをコード化できる
- HashiCorp社が開発元。HashiCorp社とコミュニティで開発・メンテナンスを行なっている
IaCのメリット
「なぜ IaCをするのか?」ということです。
- バージョン管理ができるので、インフラの変更履歴を追うことができる。
- コードレビューができる。
- 再利用、横展開がし易い。
ただこれらのメリットは他のIaCツール、例えばCloudFormationなどでも享受できるメリットです。なぜTerraformを使うのか、Terraformの良い点について、説明します。
Terraformの魅力1: シンプル
HCL
TerraformはHCL=HashiCorp Configuration Language という書式でコードを書きます。このHCLが非常に直感的で読みやすいです。プログラムを書いたこと無いよ、という方でもとっつきやすいと思います。
柔軟
書き方の自由度が高いです。Terraformは前述のHCLという書式で、.tf
という拡張子のファイルにコードを書いていくのですが、その際、ファイルの分割単位は好きにして良いです。1つのファイルに全部の設定を書いてもいいですし、同じディレクトリ上であれば自分の好きな単位、読みやすい単位でファイル分割して書いても良いです。
また、記載順も好きにできます。リソースAとリソースBについての記述があったとして、この記載順が逆になっても問題ないです。Terraformはリソース間の依存関係を把握し、正しい順序で処理してくれます。
※ ファイル分割単位、記載順ともにベスプラはあります。 Style Guide - Configuration Language | Terraform | HashiCorp Developer
コマンドが簡単
コマンドも簡単です。最低限terraform init
とterraform apply
だけ使えればIaCできます。
Terraformの魅力2: 活躍域が広い
TerraformはAWS専用IaCツールではないです。GoogleCloudなど他のクラウドサービスでも使えますし、KubernetesリソースやVM、SaaSの設定などにも使えます。ですので今後AWSを使わない現場や会社に行ったとしても、お持ちのTerraformのスキルを活かすことができます。Terraformのスキルを身につけるというのはキャリアにとってひとつとても良い選択肢なのではと思います。
Terraformの魅力3: 情報の豊富さ
まず公式ドキュメントが充実しています。各種文法やコマンドなどのドキュメントページがしっかり整備されています。チュートリアルもたくさんあります。(ただ、残念ながら英語版しかありません)
また、Terraformは約10年前に誕生した、成熟したツールです。たくさんの使用実績があり、すでに様々な情報がネット上にあります。何か問題が起きても、ググればすぐにその解決策が見つかるはずです。
Terraformの使い方
ざっくりTerraformの使い方をお伝えします。
1. インストール
TerraformのCLIをローカル端末にインストールする必要があります。以下を参照ください。
2. コードを書く
以下は、バケット名を指定したS3バケットを一つ作成するコードです。
バケットについてのコードは最下段の3行です。他はTerraform全体についての設定を書いています。
terraform {
required_version = "= 1.9.1"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.58.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
resource "aws_s3_bucket" "test" {
bucket = "devio-osaka-2024"
}
3. terraform init コマンド
いわゆる初期化処理を行うコマンドです。こちらは基本的に最初に1回実行すればOKです。
4. (クレデンシャル取得)
このあたりでAWSのクレデンシャルを取得して、リソースを作成できる権限を持っておいてください。
5. terraform apply コマンド
このコマンドを実行すると、「こういう処理を行いますが良いですか?」といった感じでdiffが表示されます。今回の例ですとS3バケットを作成するコードなので、S3バケットを作るというdiffが表示されます。そのバケットの設定値を詳細に確認することもできます。指定した通りのバケット名になることがわかりますね。
6. type "yes"
上記diffの下に
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
というテキストと共に「Enter a value: 」というプロンプトが表示されます。ここでyes
とタイプすると、前述の処理(ここではバケット作成)が実行されて、プロビジョニング完了です。
今後は、「コード書き足す」 → 「terraform apply
でdiff確認」 → 「type "yes"」の流れを繰り返すことで、IaCを進めていくことができます。
Terraformの仕組み
ここからはTerraformの仕組みについて軽く解説します。
Terraformとは(ざっくり)
ざっくりいうとTerraformとは、作りたいリソース(例えばAWS)の「APIをいい感じに実行してくれる」IaCツールです。
図にするとこうです。
開発者がterraform apply
でリソース作成をTerraformに指示すると、Terraformがあなたの代わりにAWSのAPIを実行してくれて、リソースが作成されます。
API
ご存知かもしれませんが、AWSのほとんどのアクションはAPI化されています。以下はS3のCreateBucketのAPIのドキュメントページです。
先程「Terraformの使い方」の項にてS3バケットを一つ作るTerraformコードを作ってterraform apply
しましたが、あのとき裏でTerraformはこのAPIを実行しています。
ただ、先程私は「APIをいい感じに実行してくれる」と言いました。この「APIをいい感じに実行する」というのはどういうことでしょうか?説明していきます。
「APIをいい感じに実行する」とは
先程の図の再掲です。これをより詳細に説明すると以下の図になります。
開発者がterraform apply
するところまでは同じです。そのあとStateファイルという新キャラが登場していて、Terraformがそれを読みに行っています。まずはStateファイルを説明しましょう。
Stateファイル
その名の通りですが、Terraformで管理しているリソースの「現在の状態」が格納されているファイルです。
デフォルトだとTerraformが実行されるのと同じディレクトリに、terraform.tfstate
という名前で作成されます。
設定次第ではS3バケット上に置くなどできます。ローカルにあると他の開発者がアクセスできなくて不便なので、大抵のプロジェクトではS3バケット上に置くことが多いです。
リソースの現在の状態が確認されているとはどういうことなのか、実際にStateファイルの中を覗いて確認してみましょう。
resource "aws_s3_bucket" "test" {
bucket = "devio-osaka-2024"
}
先ほど、上記のようなS3バケットを一つ作るTerraformコードを作成しました。これをterraform apply
してバケット作成すると、Stateファイルの中身は以下のようになります。
コード内容と同じように、 aws_s3_bucket
タイプのtest
という名前のリソースについての情報がありますね。で、下の方にそのバケットの設定値がズラッと記載されています。コード内で指定したバケット名についてもありますね。
再び 「APIをいい感じに実行する」とは
もう一度図に戻ります。
開発者がterraform applyを実行すると、Terraformはまず今ご説明したStateファイルを読みに行きます(2.readの部分)。このStateファイルの中には各リソースのIDも記載されています。S3バケットの場合はバケット名がIDになりますね。そのIDを使って参照系のAPIを実行します(3. API (READ))。getなんたらとかdescribeなんとかとかのAPIですね。それによってそのリソースの現状の設定を確認します。
もし現状の設定がStateファイル記載内容と異なっていた場合、例えばだれかがTerraform外で、マネジメントコンソールで設定変更したとかですね、Terraformはその変更もStateファイルに反映します(4. update)。
その後ですね、TerraformはコードとStateファイル、つまりリソースの現状とのdiffを表示します(5. diff between code and state)。
最後に、その差分を埋めるべく、適切な更新系のAPIを実行します(6. API (CREATE/UPDATE/DELETE or nothing))。
「6. API (CREATE/UPDATE/DELETE or nothing)」のところ、重要なので繰り返します。Terraformは、リソースの現状とコードの間の差分を埋めるために、適宜適切なAPI=Create、Update、Delete系のAPIを実行する、あるいは必要ないときは実行しない、というのをいい感じに使い分けてくれます。これがTerraformの仕組みです。
あらためて、「APIをいい感じに実行する」を言い換えると、以下となります。「APIを冪等的に実行する」です。
ここからTerraform Tips集
Terraformの仕組み、なんとなくご理解いただけましたでしょうか。ここからはすでにTerraformを使われている方向けにいくつかTipsをご紹介します。
TerraformのVersionを簡単に切り替える
プロジェクトAでは version1.9.3のTerraformを使っているけど、プロジェクトBではまだ1.7.0みたいな状況のことです。
実はTerraform自体にはVersionを切り替える仕組みがありません。インストールし直すしかないです。そんな事やってられないので、以下ツールを是非お使いください。
tfenv
このtfenvというツールをインストールしたうえで、Terraformを実行するディレクトリ上に.terraform-version
ファイルを作成し、その中に min-required
と書いておきます。
それだけで、先程ご説明した terraform init
時に、コード内に書かれたVersionの設定を読んで、それに合うVersionのTerraformをインストールして使ってくれるようになります。
これによって、各開発者はローカルに今入っているTerraformのVersionを気にしなくて良くなる(勝手に切り替えてくれるから)ので、非常に快適です。
詳細は以下をご参照ください。
クレデンシャルを簡単に切り替える
環境というのは dev/stg/prodみたいなやつのことです。
このケースは普通にありえるというか、むしろAWSのベストプラクティスとしては環境やワークロード毎にAWSアカウントを分離することを推奨しています。
AWSアカウントが違うということは、つまり使用するAWSのクレデンシャルを切り替えないといけないということですね。
かつ、仮に間違ったクレデンシャルを使ってTerraformを実行してしまうと、要らないリソースを作ってしまったりだとか、プロビジョニング済のリソースを削除してしまったりと言った大事故に繋がる恐れがあります。絶対にミスりたくないですね。ですので、次のツールを使ってみてください。
direnv
こちらは、特定のディレクトリに移動した際に実行されるスクリプトを書ける、というツールです。
そして大抵の場合、Terraformを実行するディレクトリとそこで使うクレデンシャル、つまりはプロビジョニング先のAWSアカウントって1対1の関係で紐づいていると思います。ですので、そのdirenvスクリプトの中で適切なAWSアカウントのIAMロールに assume roleするような処理を実行するようにすれば、クレデンシャル間違いは発生しなくなります。また、ディレクトリ移動だけで自動でクレデンシャル取得が実行されるので非常に楽です。
詳細は以下をご参照ください。
Terraformを高速化する
前述の図の3番と6番のAPIを実行する部分、この部分はデフォルトでは並列度10で実行されます。ですが設定次第でこの並列度を上げることができます。
parallelism オプション
terraform plan
や terraform apply
にオプション指定することで実現できます。または代わりに環境変数で指定することも可能です。
実際に弊社内で以下のように劇的に実行時間を改善できた事がありました。
これは確か400リソースくらい管理しているTerraformコードだったので、同じような結果をみなさんが得ることはなかなか難しいかもしれません。ですが、terraform plan
や terraform apply
コマンドは日常的に使うコマンドですので、都度の実行時間が少しでも短縮できればチリツモで効いてくるのではないかと思います。私はdirenvの中で環境変数を指定しています。
HCP Terraform(旧名:Terraform Cloud)を使う
HCP TerraformはTerraformのSaaSです。HashiCorp社が提供しています。
Terraformを利用する上で便利な様々な機能がすぐに使える、といったSaaSです。
そしてこの便利な機能にTerraform利用を寄せていくことで、ゆくゆくはTerraformの利用方法を会社内で標準化するのにも役立ちます。
今回はみっつ、HCP Terraformの良い点をご紹介します。
メリット1: Terraform実行環境を統一できる
「Terraformの使い方」の項でご紹介した通り、Terraformは基本的にはローカル端末にてCLIをインストールして、ローカルから実行するツールです。
ですがローカルから実行することによって、次のような問題が発生する場合があります。
まず、各開発者にAWSの強い権限を付与する必要があります。Terraformで作成するAWSリソースがプロジェクト開始時に厳格に決まっていることなんてほぼ無いので、大体の場合余裕のある強めの権限、AdministratorAccess権限などを付与することが多いかと思います。これがセキュリティリスクにもなりますし、また開発者の異動が激しい場合は設定変更も手間になります。
また、ローカル環境差異による問題というのも稀に発生します。Windows端末とMac端末ではTerraformの実行結果がやや異なる、みたいなケースです。
同じことがローカル環境とCDパイプライン間でも発生し得ります。ローカルでは動くけどCDパイプラインだとうまく動かない…みたいなケースですね。
HCP Terraformの場合、ローカルからコマンドを実行しても、実行環境はHCP Terraform上(のVM)にすることができます。どこからコマンド実行しても同じ実行環境上で実行されますので、前述のような環境差異による問題が発生しなくなります。また、各開発者にAWSの強権限を付与する必要もなくなります。
メリット2: CDパイプラインをすぐに作れる
これが一番大きいメリットなのではと思います。Gitリポジトリと連携したTerraformのCDパイプラインがすぐに作れます。
HCPTerraformのWeb UIとGitHub上でそれぞれいくつか設定ポチポチするだけで、以下のようなパイプラインが作成できます。
git pushしただけで自動でterraform plan
が実行され、結果のdiffがWeb UIから確認できます。この例だと EC2インスタンスを1台作成するというdiffが生成されています。緑の「+」の部分をクリックすれば、EC2インスタンスの設定も細かく確認できます。
そしてapplyはペンディング状態になっています。最下部にある青い「Confirm & apply」ボタン押下でterraform apply
を開始できます。つまりは承認フェーズ付きのCDパイプラインを簡単に作成できるというわけです。
別に他のサービスを使ってCDパイプラインを作ることもできますが、TerraformのCDパイプラインについてはHCP Terraformが一番カンタンに、かつ質の良いものが作成できるのではと思います。
メリット3: Stateファイルを簡単に安全に管理できる
先ほどStateファイルの説明の際に、S3バケット上に置くことができると説明しました。
Stateファイルにはリソースの情報が色々と記録されています。例えばRDSをTerraformで作成した場合、そのパスワードもStateファイルには記録されています。ですので厳重に扱わないといけないファイルです。
S3バケット上に置くことができますが、そのS3バケットの設定を色々と行わないといけませんし、そのバケットのIaCをどうやってやるかも考えないといけません。(Terraformコード内でプロビジョニングすることもできますが、そうすると色々面倒なことが発生するので、できればTerraform外で作成した方がよいです。)
HCP Terraformの場合、S3バケットを用意、設定する必要はありません。HCP Terraform側で管理してくれます。なおかつS3だと自分で設定が必要だったバージョニング、暗号化などもデフォルトで組み込まれています。アクセス制限も細かく設定可能です。
さらに、Stateの変更履歴をWeb UIから確認することができます。以下の例だと履歴が3件あることがわかります。
さらに、各履歴の詳細も確認でき、具体的にどのような変更があったのか把握可能です。
このページ上には紐づくgit コミットのリンクもあります。
このStateファイルについての詳細は以下ブログをご参照ください。
価格
他にもHCP Terraformは便利機能が色々あるのですが、気になるのはお値段だとおもいます。こちら、無料で始められます。
月あたり 500リソースまでならHCP Terraformで管理しても無料でご利用いただけます。
500リソースって結構多いので、最初のうちは全然無料利用枠内で収まるのではないかなと思います。ただし有償版やさらに一つ上のプラン(HCP Plus)でないと利用できない機能というものもありますので、その点はご注意ください。
そして、HCP Terraformは弊社クラスメソッド経由でもご契約いただけます。
弊社経由でご契約いただきますと、AWS利用費とHCP Terraform利用費まとめて請求させていただくこともできて非常に便利です。ぜひ弊社経由のご契約もご検討ください。
そのほか同社では、Terraform Cloud(現:HCP Terraform)をクラスメソッドのCPPO経由で利用しています。以前からTerraformでAWSのインフラを構成・管理していましたが、「エンジニア間の作業のバッティングがあった」といいます。
「サービス開発のなかで、あるエンジニアが書いたコードを、他のメンバーが気がつかずに上書きしてしまったり、あとから振り返ってメンバーの作業内容が分からなかったりするという課題がありました。チーム開発の統制が取れない状況を是正するため、Terraform Cloudを導入しました。クラスメソッド経由にしたのは、AWSの費用と合算請求になるので、事務処理が楽だからです。ドルではなく円払いできるのもうれしいですね」
-
引用元: ヤプリ様事例|クラスメソッドメンバーズ加入でAWSのコスト削減に成功。ノーコード開発ツール「Yappli」で幅広い業種・企業のDXを支援|クラスメソッド
-
HCP Terraform Plus / Terraform Enterprise の導入支援 | クラスメソッド株式会社
まとめ
冒頭で「Terraform」の正しいアクセントの話をしてしまったせいで、登壇中「今言った「Terraform」のアクセント合ってたっけ?」「あ、またアクセント間違えたわ」と気になって勝手に一人で混乱していました笑 正しく発音できるように精進して参ります。